{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://github.com/retkowsky/visual-search-azureAI/blob/main/logo.jpg?raw=true\">\n",
    "\n",
    "# Fashion Visual Search demo\n",
    "\n",
    "## 4. Visual search webapp\n",
    "\n",
    "This code demonstrates how to use **Azure Cognitive Search** with **Cognitive Services Florence Vision API** and Azure Python SDK for visual search.\n",
    "\n",
    "\n",
    "## Steps\n",
    "- Connect to a blob storage where your catalog images are\n",
    "- Use Azure Computer Vision 4 to embed all these images\n",
    "- Create an Azure Cognitive search vector store index\n",
    "- Upload the embeddings into an Azure Cognitive Search index\n",
    "- Do some visual search using a prompt or an image\n",
    "\n",
    "\n",
    "## Visual search with vector embeddings\n",
    "Vector embeddings are a way of representing content such as text or images as vectors of real numbers in a high-dimensional space. These embeddings are often learned from large amounts of textual and visual data using machine learning algorithms like neural networks. Each dimension of the vector corresponds to a different feature or attribute of the content, such as its semantic meaning, syntactic role, or context in which it commonly appears. By representing content as vectors, we can perform mathematical operations on them to compare their similarity or use them as inputs to machine learning models.\n",
    "\n",
    "## Process\n",
    "<img src=\"https://raw.githubusercontent.com/retkowsky/Azure-Computer-Vision-in-a-day-workshop/72c07afc4fcc04a29ca19b84d3d343a09a22368e//fashionprocess.png\" width=512>\n",
    "\n",
    "## Business applications\n",
    "- Digital asset management: Image retrieval can be used to manage large collections of digital images, such as in museums, archives, or online galleries. Users can search for images based on visual features and retrieve the images that match their criteria.\n",
    "- Medical image retrieval: Image retrieval can be used in medical imaging to search for images based on their diagnostic features or disease patterns. This can help doctors or researchers to identify similar cases or track disease progression.\n",
    "- Security and surveillance: Image retrieval can be used in security and surveillance systems to search for images based on specific features or patterns, such as in, people & object tracking, or threat detection.\n",
    "- Forensic image retrieval: Image retrieval can be used in forensic investigations to search for images based on their visual content or metadata, such as in cases of cyber-crime.\n",
    "- E-commerce: Image retrieval can be used in online shopping applications to search for similar products based on their features or descriptions or provide recommendations based on previous purchases.\n",
    "- Fashion and design: Image retrieval can be used in fashion and design to search for images based on their visual features, such as color, pattern, or texture. This can help designers or retailers to identify similar products or trends.\n",
    "\n",
    "## To learn more\n",
    "- https://learn.microsoft.com/en-us/azure/cognitive-services/computer-vision/concept-image-retrieval\n",
    "- https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search\n",
    "\n",
    "In this notebook we took some samples fashion images are taken from this link:<br>\n",
    "https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset\n",
    "\n",
    "> Note: Image retrieval is curently in public preview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Python librairies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime\n",
    "import io\n",
    "import json\n",
    "import os\n",
    "import requests\n",
    "import sys\n",
    "import gradio as gr\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "from PIL import Image\n",
    "\n",
    "from azure.core.credentials import AzureKeyCredential\n",
    "from azure.search.documents import SearchClient\n",
    "from azure.search.documents.indexes import SearchIndexClient\n",
    "from azure.search.documents.models import Vector\n",
    "\n",
    "from azure.storage.blob import BlobServiceClient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3.8.5 (default, Sep  4 2020, 07:30:14) \\n[GCC 7.3.0]'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sys.version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Today is 2023-06-30 07:49:41.488610\n"
     ]
    }
   ],
   "source": [
    "print(\"Today is\", datetime.datetime.today())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Azure AI Services"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "load_dotenv(\"azure.env\")\n",
    "\n",
    "# Azure Computer Vision 4\n",
    "acv_key = os.getenv(\"acv_key\")\n",
    "acv_endpoint = os.getenv(\"acv_endpoint\")\n",
    "\n",
    "# Azure Cognitive Search\n",
    "acs_endpoint = os.getenv(\"acs_endpoint\")\n",
    "acs_key = os.getenv(\"acs_key\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ensure that the azure endpoints should not finished a /\n",
    "if acv_endpoint.endswith(\"/\"):\n",
    "    acv_endpoint = acv_endpoint[:-1]\n",
    "\n",
    "if acs_endpoint.endswith(\"/\"):\n",
    "    acs_endpoint = acv_endpoint[:-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Azure storage account\n",
    "blob_connection_string = os.getenv(\"blob_connection_string\")\n",
    "container_name = os.getenv(\"container_name\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Functions & parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Azure Cognitive Search index name to create\n",
    "index_name = \"azure-fashion-demo\"\n",
    "\n",
    "# Azure Cognitive Search api version\n",
    "api_version = \"2023-02-01-preview\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def text_embedding(prompt):\n",
    "    \"\"\"\n",
    "    Text embedding using Azure Computer Vision 4.0\n",
    "    \"\"\"\n",
    "    version = \"?api-version=\" + api_version + \"&modelVersion=latest\"\n",
    "    vec_txt_url = f\"{acv_endpoint}/computervision/retrieval:vectorizeText{version}\"\n",
    "    headers = {\"Content-type\": \"application/json\", \"Ocp-Apim-Subscription-Key\": acv_key}\n",
    "\n",
    "    payload = {\"text\": prompt}\n",
    "    response = requests.post(vec_txt_url, json=payload, headers=headers)\n",
    "\n",
    "    if response.status_code == 200:\n",
    "        text_emb = response.json().get(\"vector\")\n",
    "        return text_emb\n",
    "\n",
    "    else:\n",
    "        print(f\"Error: {response.status_code} - {response.text}\")\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def index_stats(index_name):\n",
    "    \"\"\"\n",
    "    Get statistics about Azure Cognitive Search index\n",
    "    \"\"\"\n",
    "    url = (\n",
    "        acs_endpoint\n",
    "        + \"/indexes/\"\n",
    "        + index_name\n",
    "        + \"/stats?api-version=2021-04-30-Preview\"\n",
    "    )\n",
    "    headers = {\n",
    "        \"Content-Type\": \"application/json\",\n",
    "        \"api-key\": acs_key,\n",
    "    }\n",
    "    response = requests.get(url, headers=headers)\n",
    "    print(\"Azure Cognitive Search index status for:\", index_name, \"\\n\")\n",
    "\n",
    "    if response.status_code == 200:\n",
    "        res = response.json()\n",
    "        print(json.dumps(res, indent=2))\n",
    "\n",
    "    else:\n",
    "        print(\"Request failed with status code:\", response.status_code)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def index_status(index_name):\n",
    "    \"\"\"\n",
    "    Azure Cognitive Search index status\n",
    "    \"\"\"\n",
    "    print(\"Azure Cognitive Search Index:\", index_name, \"\\n\")\n",
    "\n",
    "    headers = {\"Content-Type\": \"application/json\", \"api-key\": acs_key}\n",
    "    params = {\"api-version\": \"2021-04-30-Preview\"}\n",
    "    index_status = requests.get(\n",
    "        acs_endpoint + \"/indexes/\" + index_name, headers=headers, params=params\n",
    "    )\n",
    "    try:\n",
    "        print(json.dumps((index_status.json()), indent=5))\n",
    "    except:\n",
    "        print(\"Request failed\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "URL of the first blob: https://azurestorageaccountsr.blob.core.windows.net/fashionimages/fashion/0390469004.jpg\n"
     ]
    }
   ],
   "source": [
    "# Connect to Blob Storage\n",
    "blob_service_client = BlobServiceClient.from_connection_string(blob_connection_string)\n",
    "container_client = blob_service_client.get_container_client(container_name)\n",
    "blobs = container_client.list_blobs()\n",
    "\n",
    "first_blob = next(blobs)\n",
    "blob_url = container_client.get_blob_client(first_blob).url\n",
    "print(f\"URL of the first blob: {blob_url}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Azure Cognitive Search"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Setting the Azure Cognitive Search client\n",
      "Done\n",
      "<azure.search.documents.indexes._search_index_client.SearchIndexClient object at 0x7f1ab8f0ceb0>\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    # Setting the Azure Cognitive Search client\n",
    "    print(\"Setting the Azure Cognitive Search client\")\n",
    "    search_client = SearchIndexClient(\n",
    "        endpoint=acs_endpoint, credential=AzureKeyCredential(acs_key)\n",
    "    )\n",
    "    print(\"Done\")\n",
    "    print(search_client)\n",
    "\n",
    "except:\n",
    "    print(\"Request failed. Cannot create Azure Cognitive Search client:\", acs_endpoint)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Azure Cognitive Search index status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Azure Cognitive Search index status for: azure-fashion-demo \n",
      "\n",
      "{\n",
      "  \"@odata.context\": \"https://azurecogsearcheastussr.search.windows.net/$metadata#Microsoft.Azure.Search.V2021_04_30_Preview.IndexStatistics\",\n",
      "  \"documentCount\": 10226,\n",
      "  \"storageSize\": 155596726\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "index_stats(index_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Azure Cognitive Search Index: azure-fashion-demo \n",
      "\n",
      "{\n",
      "     \"@odata.context\": \"https://azurecogsearcheastussr.search.windows.net/$metadata#indexes/$entity\",\n",
      "     \"@odata.etag\": \"\\\"0x8DB7639E6632A9E\\\"\",\n",
      "     \"name\": \"azure-fashion-demo\",\n",
      "     \"defaultScoringProfile\": null,\n",
      "     \"fields\": [\n",
      "          {\n",
      "               \"name\": \"idfile\",\n",
      "               \"type\": \"Edm.String\",\n",
      "               \"searchable\": false,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": true,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          },\n",
      "          {\n",
      "               \"name\": \"imagefile\",\n",
      "               \"type\": \"Edm.String\",\n",
      "               \"searchable\": true,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": false,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          },\n",
      "          {\n",
      "               \"name\": \"imagevector\",\n",
      "               \"type\": \"Collection(Edm.Single)\",\n",
      "               \"searchable\": true,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": false,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          }\n",
      "     ],\n",
      "     \"scoringProfiles\": [],\n",
      "     \"corsOptions\": null,\n",
      "     \"suggesters\": [],\n",
      "     \"analyzers\": [],\n",
      "     \"normalizers\": [],\n",
      "     \"tokenizers\": [],\n",
      "     \"tokenFilters\": [],\n",
      "     \"charFilters\": [],\n",
      "     \"encryptionKey\": null,\n",
      "     \"similarity\": {\n",
      "          \"@odata.type\": \"#Microsoft.Azure.Search.BM25Similarity\",\n",
      "          \"k1\": null,\n",
      "          \"b\": null\n",
      "     },\n",
      "     \"semantic\": {\n",
      "          \"defaultConfiguration\": null,\n",
      "          \"configurations\": [\n",
      "               {\n",
      "                    \"name\": \"my-semantic-config\",\n",
      "                    \"prioritizedFields\": {\n",
      "                         \"titleField\": {\n",
      "                              \"fieldName\": \"idfile\"\n",
      "                         },\n",
      "                         \"prioritizedContentFields\": [],\n",
      "                         \"prioritizedKeywordsFields\": []\n",
      "                    }\n",
      "               }\n",
      "          ]\n",
      "     }\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "index_status(index_name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Webapp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "topn = 5\n",
    "imgsize = 360\n",
    "\n",
    "footnote = \"Powered by Azure Computer Vision & Azure Cognitive Search\"\n",
    "header_prompt = \"Visual Search with Azure AI using a prompt\"\n",
    "header_images = \"Visual Search with Azure AI using a prompt\"\n",
    "\n",
    "logo = \"https://github.com/retkowsky/visual-search-azureAI/blob/main/logo.jpg?raw=true\"\n",
    "image = \"<center> <img src= {} width=512px></center>\".format(logo)\n",
    "\n",
    "# Themes: https://huggingface.co/spaces/gradio/theme-gallery\n",
    "theme = \"snehilsanyal/scikit-learn\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prompt_search_gradio(prompt, topn=5):\n",
    "    \"\"\"\n",
    "    Prompt search for the gradio webapp\n",
    "    \"\"\"\n",
    "    results_list = []\n",
    "    images_list = []\n",
    "\n",
    "    # Initialize the Azure Cognitive Search client\n",
    "    search_client = SearchClient(acs_endpoint, index_name, AzureKeyCredential(acs_key))\n",
    "    # Perform vector search\n",
    "    vector = Vector(value=text_embedding(prompt), k=topn, fields=\"imagevector\")\n",
    "    response = search_client.search(\n",
    "        search_text=prompt, vector=vector, select=[\"idfile\", \"imagefile\"]\n",
    "    )\n",
    "\n",
    "    for result in response:\n",
    "        image_file = result[\"imagefile\"]\n",
    "        results_list.append(image_file)\n",
    "\n",
    "    for image_file in results_list:\n",
    "        blob_client = container_client.get_blob_client(image_file)\n",
    "        blob_image = blob_client.download_blob().readall()\n",
    "        img = Image.open(io.BytesIO(blob_image)).resize((imgsize, imgsize))\n",
    "        images_list.append(img)\n",
    "\n",
    "    return images_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt_examples = [\n",
    "    \"a red dress\",\n",
    "    \"a red dress with long sleeves\",\n",
    "    \"Articles with birds\",\n",
    "    \"Hair products\",\n",
    "    \"Ray-Ban\",\n",
    "    \"NYC cap\",\n",
    "    \"Camo products\",\n",
    "    \"A blue shirt with stripped lines\",\n",
    "    \"Ray ban with leopard frames\",\n",
    "    \"Show me some articles with Italian names\",\n",
    "    \"Show me some articles with Japanese on it\",\n",
    "    \"Show me some tie-dye articles\",\n",
    "]\n",
    "\n",
    "prompt = gr.components.Textbox(\n",
    "    lines=2,\n",
    "    label=\"What do you want to search?\",\n",
    "    placeholder=\"Enter your prompt for the visual search...\",\n",
    ")\n",
    "\n",
    "topn_list_prompt = [\"\"] * topn\n",
    "\n",
    "list_img_results_image = [\n",
    "    gr.components.Image(label=f\"Top {i+1}: {topn_list_prompt[i]}\", type=\"filepath\")\n",
    "    for i in range(topn)\n",
    "]\n",
    "\n",
    "webapp_prompt = gr.Interface(\n",
    "    prompt_search_gradio,\n",
    "    prompt,\n",
    "    list_img_results_image,\n",
    "    title=header_prompt,\n",
    "    examples=prompt_examples,\n",
    "    theme=theme,\n",
    "    description=image,\n",
    "    article=footnote,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# webapp_prompt.launch(share=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def image_embedding(imagefile):\n",
    "    \"\"\"\n",
    "    Image embedding using Azure Computer Vision 4.0\n",
    "    \"\"\"\n",
    "    session = requests.Session()\n",
    "\n",
    "    version = \"?api-version=\" + api_version + \"&modelVersion=latest\"\n",
    "    vec_img_url = acv_endpoint + \"/computervision/retrieval:vectorizeImage\" + version\n",
    "    headers = {\n",
    "        \"Content-type\": \"application/octet-stream\",\n",
    "        \"Ocp-Apim-Subscription-Key\": acv_key,\n",
    "    }\n",
    "\n",
    "    try:\n",
    "        with open(imagefile, \"rb\") as f:\n",
    "            data = f.read()\n",
    "        response = session.post(vec_img_url, data=data, headers=headers)\n",
    "        response.raise_for_status()\n",
    "\n",
    "        image_emb = response.json()[\"vector\"]\n",
    "        return image_emb\n",
    "\n",
    "    except requests.exceptions.RequestException as e:\n",
    "        print(f\"Request Exception: {e}\")\n",
    "    except Exception as ex:\n",
    "        print(f\"Error: {ex}\")\n",
    "\n",
    "    return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def image_search_gradio(imagefile, topn=5):\n",
    "    \"\"\"\n",
    "    Image search for the gradio webapp\n",
    "    \"\"\"\n",
    "    results_list = []\n",
    "    images_list = []\n",
    "\n",
    "    # Initialize the Azure Cognitive Search client\n",
    "    search_client = SearchClient(acs_endpoint, index_name, AzureKeyCredential(acs_key))\n",
    "\n",
    "    # Perform vector search\n",
    "    response = search_client.search(\n",
    "        search_text=\"\",\n",
    "        vector=Vector(value=image_embedding(imagefile), k=topn, fields=\"imagevector\"),\n",
    "        select=[\"idfile\", \"imagefile\"],\n",
    "    )\n",
    "\n",
    "    for result in response:\n",
    "        image_file = result[\"imagefile\"]\n",
    "        results_list.append(image_file)\n",
    "\n",
    "    for image_file in results_list:\n",
    "        blob_client = container_client.get_blob_client(image_file)\n",
    "        blob_image = blob_client.download_blob().readall()\n",
    "        img = Image.open(io.BytesIO(blob_image)).resize((imgsize, imgsize))\n",
    "        images_list.append(img)\n",
    "\n",
    "    return images_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "images_examples = [\n",
    "    \"images/image1.jpg\",\n",
    "    \"images/image2.jpg\",\n",
    "    \"images/image3.jpg\",\n",
    "    \"images/image4.jpg\",\n",
    "    \"images/image5.jpg\",\n",
    "    \"images/image6.jpg\",\n",
    "    \"images/image7.jpg\",\n",
    "    \"images/image8.jpg\",\n",
    "]\n",
    "\n",
    "refimage = gr.components.Image(label=\"Your image:\", type=\"filepath\", shape=((imgsize, imgsize)))\n",
    "topn_list_prompt = [\"\"] * topn\n",
    "\n",
    "list_img_results_image = [\n",
    "    gr.components.Image(label=f\"Top {i+1} : {topn_list_prompt[i]}\", type=\"filepath\")\n",
    "    for i in range(topn)\n",
    "]\n",
    "\n",
    "webapp_image = gr.Interface(\n",
    "    image_search_gradio,\n",
    "    refimage,\n",
    "    list_img_results_image,\n",
    "    title=header_images,\n",
    "    examples=images_examples,\n",
    "    theme=theme,\n",
    "    description=image,\n",
    "    article=footnote,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# webapp_image.launch(share=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Combining the two gradio apps into one"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/anaconda/envs/jupyter_env/lib/python3.8/site-packages/gradio/blocks.py:922: UserWarning: api_name predict already exists, using predict_1\n",
      "  warnings.warn(\n",
      "/anaconda/envs/jupyter_env/lib/python3.8/site-packages/gradio/blocks.py:922: UserWarning: api_name load_example already exists, using load_example_1\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "visual_search_webapp = gr.TabbedInterface(\n",
    "    [webapp_prompt, webapp_image],\n",
    "    [\n",
    "        \"1) Visual search from a prompt\",\n",
    "        \"2) Visual search from an image\"\n",
    "    ],\n",
    "    css=\"body {background-color: black}\",\n",
    "    theme=theme,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running on local URL:  http://127.0.0.1:7860\n",
      "Running on public URL: https://828c9920912687a0b6.gradio.live\n",
      "\n",
      "This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div><iframe src=\"https://828c9920912687a0b6.gradio.live\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visual_search_webapp.launch(share=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Post processing\n",
    "\n",
    "We can delete the index if needed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Azure Cognitive Search Index: azure-fashion-demo \n",
      "\n",
      "{\n",
      "     \"@odata.context\": \"https://azurecogsearcheastussr.search.windows.net/$metadata#indexes/$entity\",\n",
      "     \"@odata.etag\": \"\\\"0x8DB7639E6632A9E\\\"\",\n",
      "     \"name\": \"azure-fashion-demo\",\n",
      "     \"defaultScoringProfile\": null,\n",
      "     \"fields\": [\n",
      "          {\n",
      "               \"name\": \"idfile\",\n",
      "               \"type\": \"Edm.String\",\n",
      "               \"searchable\": false,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": true,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          },\n",
      "          {\n",
      "               \"name\": \"imagefile\",\n",
      "               \"type\": \"Edm.String\",\n",
      "               \"searchable\": true,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": false,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          },\n",
      "          {\n",
      "               \"name\": \"imagevector\",\n",
      "               \"type\": \"Collection(Edm.Single)\",\n",
      "               \"searchable\": true,\n",
      "               \"filterable\": false,\n",
      "               \"retrievable\": true,\n",
      "               \"sortable\": false,\n",
      "               \"facetable\": false,\n",
      "               \"key\": false,\n",
      "               \"indexAnalyzer\": null,\n",
      "               \"searchAnalyzer\": null,\n",
      "               \"analyzer\": null,\n",
      "               \"normalizer\": null,\n",
      "               \"synonymMaps\": []\n",
      "          }\n",
      "     ],\n",
      "     \"scoringProfiles\": [],\n",
      "     \"corsOptions\": null,\n",
      "     \"suggesters\": [],\n",
      "     \"analyzers\": [],\n",
      "     \"normalizers\": [],\n",
      "     \"tokenizers\": [],\n",
      "     \"tokenFilters\": [],\n",
      "     \"charFilters\": [],\n",
      "     \"encryptionKey\": null,\n",
      "     \"similarity\": {\n",
      "          \"@odata.type\": \"#Microsoft.Azure.Search.BM25Similarity\",\n",
      "          \"k1\": null,\n",
      "          \"b\": null\n",
      "     },\n",
      "     \"semantic\": {\n",
      "          \"defaultConfiguration\": null,\n",
      "          \"configurations\": [\n",
      "               {\n",
      "                    \"name\": \"my-semantic-config\",\n",
      "                    \"prioritizedFields\": {\n",
      "                         \"titleField\": {\n",
      "                              \"fieldName\": \"idfile\"\n",
      "                         },\n",
      "                         \"prioritizedContentFields\": [],\n",
      "                         \"prioritizedKeywordsFields\": []\n",
      "                    }\n",
      "               }\n",
      "          ]\n",
      "     }\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "index_status(index_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Azure Cognitive Search index status for: azure-fashion-demo \n",
      "\n",
      "{\n",
      "  \"@odata.context\": \"https://azurecogsearcheastussr.search.windows.net/$metadata#Microsoft.Azure.Search.V2021_04_30_Preview.IndexStatistics\",\n",
      "  \"documentCount\": 10226,\n",
      "  \"storageSize\": 155596726\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "index_stats(index_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "# delete_index(index_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
